package jetbrains.buildServer.cuta.logic.operators;

import jetbrains.buildServer.cuta.logic.ColumnDef;
import jetbrains.buildServer.cuta.logic.sheet.Cell;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static jetbrains.buildServer.cuta.utils.DomUtil.*;
import static jetbrains.buildServer.util.StringUtil.*;



/**
 * @author Leonid Bushuev from JetBrains
 */

class ReplaceOperator extends AbstractOperator
{
    Pattern myPattern = null;
    String myTemplate = "";
    char myOnly = '\0';  // F - first line, L - last line


    @Override
    public void init(Element element, ColumnDef column, ExternalContext extContext)
    {
        String thePatternString = getAttrString(element, "pattern", "$");
        myPattern = Pattern.compile(thePatternString, Pattern.CASE_INSENSITIVE);
        myTemplate = emptyIfNull(getContent(element));
        myOnly = parseOnly(getAttrString(element, "only", null));
    }


    private char parseOnly(String only)
    {
        if (only == null || only.length() == 0)
            return '\0';

        char result = Character.toUpperCase(only.charAt(0));
        return result;
    }


    @Override
    public void run(Object object, Cell cell)
    {
        String text = cell.getText();
        if (text.contains("\n"))
        {
            boolean firstOnly = myOnly == 'F',
                    lastOnly = myOnly == 'L';

            cell.clearText();
            String[] lines = text.split("\n");
            for (int i = 0, n = lines.length; i < n; i++)
            {
                String line = lines[i];
                String result;
                result = firstOnly && i > 0 || lastOnly && i < n - 1
                        ? line
                        : processOneLine(line);
                cell.addText(result);
            }
        }
        else
        {
            String processed = processOneLine(text);
            cell.setText(processed);
        }

    }


    @NotNull
    private String processOneLine(String text)
    {
        StringBuffer buf = new StringBuffer();
        Matcher m = myPattern.matcher(text);
        while (m.find())
            m.appendReplacement(buf, myTemplate);
        m.appendTail(buf);
        return buf.toString();
    }


    @NotNull
    @Override
    public String name()
    {
        return "replace";
    }


    @Override
    public String toString()
    {
        String thePattern = myPattern != null ? myPattern.pattern() : "<nothing>";
        return name() + ' ' + thePattern + " with " + myTemplate;
    }
}
